package com.sino.business.service;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import com.sino.bean.Acl;
import com.sino.bean.Entityrolerelation;
import com.sino.bean.Role;
import com.sino.bean.TModule;
import com.sino.business.IAclService;
import com.sino.dao.IAclDAO;
import com.sino.model.ModuleModel;
import com.sino.model.StaticModel;

public class AclServiceImp implements IAclService {
	private IAclDAO aclDAO;

	/**
	 * @param aclDAO
	 *            the aclDAO to set
	 */
	public void setAclDAO(IAclDAO aclDAO) {
		this.aclDAO = aclDAO;
	}

	/**
	 * 查找列出所有模块
	 * 
	 * @return
	 */
	public List<StaticModel> listAllModule() {
		List<TModule> ls = this.aclDAO.listAllModules();
		List<StaticModel> list = new ArrayList<StaticModel>();
		for (TModule tm : ls) {
			StaticModel sm = this.getStaticModel(tm);
			list.add(sm);
		}
		return list;
	}

	/**
	 * 通过角色id查找该角色已经拥有的模块列表
	 */
	public List<StaticModel> listAuthModule(int roleId) {
		List<Acl> ls = this.aclDAO.listModuleByRole(roleId);
		List<StaticModel> list = new ArrayList<StaticModel>();
		for (Acl acl : ls) {
			StaticModel sm = this.getStaticModel(acl);
			list.add(sm);
		}
		return list;
	}

	/**
	 * 查找一个模块没有被授予的模块列表 实现原理：先查找所有的模块列表 查找一个角色所具有的模块列表 用所有的模块列表减去一个角色所具有的模块列表
	 * 将得到的模块列表返回
	 */
	public List<StaticModel> listUnAuthModule(int roleId) {
		List<StaticModel> AllModule = this.listAllModule();
		List<StaticModel> authModule = this.listAuthModule(roleId);
		String temp;
		if (null != AllModule && null != authModule) {
			for (StaticModel authSM : authModule) {
				temp = authSM.getId();
				Iterator it = AllModule.iterator();
				while (it.hasNext()) {
					StaticModel sm = (StaticModel) it.next();
					if (sm.getId().equals(temp))
						it.remove();
					continue;
				}
			}
		}
		return AllModule;
	}

	/**
	 * 权限管理中的核心函数之一，通过角色id，查找所有模块的树形列表，并将该角色所具有的模块打上勾 构造一个html字符串返回
	 */
	public String listModuleString(int roleId) {
		StringBuffer sb = new StringBuffer("");
		List<Acl> authModuleList = this.aclDAO.listModuleByRole(roleId);
		// 该用户被授权的模块ID的集合
		List<Integer> authModuleIdlist = new ArrayList<Integer>();
		for (Acl acl : authModuleList) {
			authModuleIdlist.add(acl.getModule().getId());
		}
		// 所有的父模块
		List<TModule> ParentModuleList = this.aclDAO.listAllParentModules();
		List<TModule> childModuleList = new ArrayList<TModule>();
		for (TModule parentModule : ParentModuleList) {
			sb.append("<tr><td bgcolor='#EAEEEE' class='font__12_grey'>");
			// 在所有的父模块里取到是否是在 该用户被授权的模块集合里
			// 如果有的话打上勾
			if (this.isExitInArray(parentModule.getId(), authModuleIdlist)) {
				sb.append("<input type='checkbox' name='authList' id='"
						+ parentModule.getId() + "' value='"
						+ parentModule.getId() + "' parentId='" + 0
						+ "' checked='checked'/>");
			} else {
				sb.append("<input type='checkbox' name='authList' id='"
						+ parentModule.getId() + "' value='"
						+ parentModule.getId() + "' parentId='" + 0 + "'/>");
			}
			sb.append(parentModule.getName());
			sb.append("</td></tr>");
			//通过父模块id查询所有子模块
			childModuleList = this.aclDAO
					.listAllChildModulesByParent(parentModule.getId());
			for (TModule childModule : childModuleList) {
				sb.append("<tr><td bgcolor='#EAEEEE' class='font__12_grey'>");
				if (this.isExitInArray(childModule.getId(), authModuleIdlist)) {
					sb
							.append("&nbsp;&nbsp;&nbsp;<input type='checkbox' name='authList' id='"
									+ childModule.getId()
									+ "' value='"
									+ childModule.getId()
									+ "' parentId='"
									+ parentModule.getId()
									+ "' checked='checked'/>");
				} else {
					sb
							.append("&nbsp;&nbsp;&nbsp;<input type='checkbox' name='authList' id='"
									+ childModule.getId()
									+ "' value='"
									+ childModule.getId()
									+ "' parentId='"
									+ parentModule.getId() + "'/>");
				}
				sb.append(childModule.getName());
				sb.append("</td></tr>");
			}
		}
		return sb.toString();
	}

	/**
	 * 权限管理中的核心函数之一，通过角色id，与模块列表，授予或者删除一个角色的权限 实现原理：先查找一个角色现在所授予的所有模块列表；
	 * 将现在的所有模块列表删除 判断moduleList是否为空 如果moduleList不为空，则通过循环构造acl模型，插入数据库
	 */
	public void saveOrRevokeModule(int roleId, String[] moduleList) {
		List<Acl> authList = this.aclDAO.listModuleByRole(roleId);
		if (null != authList && authList.size() > 0) {
			for (Acl acl : authList) {
				this.aclDAO.delAcl(acl);
			}
		}
		if (null != moduleList && moduleList.length > 0) {
			for (int i = 0; i < moduleList.length; i++) {
				Acl acl = new Acl();
				TModule module = this.aclDAO.fidTModuleById(new Integer(
						moduleList[i]));
				acl.setModule(module);
				Role role = this.aclDAO.findRoleById(roleId);
				acl.setRole(role);
				this.aclDAO.saveAcl(acl);
			}
		}

	}

	/**
	 * 权限管理中的核心函数之一，通过实体type与实体id查找一个实体所具有的所有模块列表
	 * type为EntityrolerelationModel中的ENTITY_USER（代表实体类型为用户）或者ENTITY_EXPERT（代表实体类型为专家）
	 * 实现原理：查找一个实体所具有的角色； 查找每个角色所具有的模块列表； 将所有模块列表综合，并去掉重复的模块；
	 * 将得到的模块列表转化成model列表并返回
	 */
	public List<ModuleModel> listPermissionByEntity(int type, int entityId) {
		List<Entityrolerelation> roleList = this.aclDAO.listRoleByEntity(type,
				entityId);// 调用aclDAO的listRoleByEntity函数，通过实体类型与实体id查找一个实体所具有的所有角色列表
		List<TModule> moduleList = new ArrayList<TModule>();// 最后返回的模块列表
		int tempId;
		boolean isExist = false;// 标识符
		for (Entityrolerelation err : roleList) {
			List<Acl> aclList = this.aclDAO.listModuleByRole(err.getRole()
					.getId());// 查找一个角色所具有的模块列表
			for (Acl acl : aclList) {// 循环该列表
				tempId = acl.getModule().getId();// 得到一个模块的id
				for (TModule module : moduleList) {// 循环最后返回的模块列表
					if (tempId == module.getId()) {// 如果该模块已经存在于最后返回的模块列表中
						isExist = true; // 如果存在则标识符为true
						break;// 退出循环
					} // 否则继续下次循环查找是否存在于列表中
				}
				if (isExist == false) { // 判断如果标示符为false（即）
					moduleList.add(acl.getModule());// 将该模块添加到最后返回的模块列表中
				}
				isExist = false; // 将标示符置为初始false，为下个角色循环做准备
			}
		}

		// 将最后返回的模块列表，转化为model列表，并返回
		List<ModuleModel> moduleModelList = new ArrayList<ModuleModel>();
		List<TModule> sortModuleList = this.sortList(moduleList);
		for (TModule module : sortModuleList) {
			ModuleModel mm = this.getModuleModel(module);
			moduleModelList.add(mm);
		}
		return moduleModelList;
	}

	/**
	 * 通过模块bean的id与name构造一个staticmodel，并返回
	 * 
	 * @param tmodule
	 * @return
	 */
	public StaticModel getStaticModel(TModule tmodule) {
		StaticModel staticModel = new StaticModel();
		staticModel.setId(tmodule.getId().toString());
		staticModel.setName(tmodule.getName());
		return staticModel;
	}

	/**
	 * 重载函数，通过acl中的模块bean的id与name够着一个staticmodel，并返回
	 * 
	 * @param acl
	 * @return
	 */
	public StaticModel getStaticModel(Acl acl) {
		StaticModel staticModel = new StaticModel();
		staticModel.setId(acl.getModule().getId().toString());
		staticModel.setName(acl.getModule().getName());
		return staticModel;
	}

	/**
	 * 将bean转化为model 获得模块model
	 * 
	 * @param tmodule
	 * @return
	 */
	private ModuleModel getModuleModel(TModule tmodule) {
		ModuleModel moduleModel = new ModuleModel();
		moduleModel.setId(tmodule.getId());
		moduleModel.setName(tmodule.getName());
		moduleModel.setOrderNum(tmodule.getOrderNum());
		moduleModel.setSn(tmodule.getSn());
		moduleModel.setTModule(tmodule.getTModule());
		moduleModel.setTModules(tmodule.getTModules());
		moduleModel.setUrl(tmodule.getUrl());
		return moduleModel;
	}

	/**
	 * 判断一个整数data是否在整数列表datas中 如果在则返回true，否则返回false
	 * 
	 * @param data
	 * @param datas
	 * @return
	 */
	public boolean isExitInArray(int data, List<Integer> datas) {
		boolean bl = false;
		for (Integer i : datas) {
			if (data == i) {
				bl = true;
				break;
			}
		}
		return bl;
	}

	/**
	 * 权限模块排序
	 * 
	 * @param oldList
	 * @return
	 */
	public List<TModule> sortList(List<TModule> oldList) {
		List<TModule> tempList = oldList;
		TModule tempTM;
		for (int i = 0; i < tempList.size(); i++) {
			Integer minFenshu = tempList.get(i).getOrderNum();
			TModule minTM = tempList.get(i);
			int minId = i;
			for (int j = i + 1; j < tempList.size(); j++) {
				if (oldList.get(j).getOrderNum() < minFenshu) {
					minFenshu = tempList.get(j).getOrderNum();
					minTM = tempList.get(j);
					minId = j;
				}
			}
			if (i != minId) {
				tempTM = tempList.get(i);
				tempList.remove(i);
				tempList.add(i, minTM);
				tempList.remove(minId);
				tempList.add(minId, tempTM);
			}
		}
		return tempList;
	}

}
